package Model.symtable;

import Model.ErrorSemantico;
import java.util.ArrayList;
import java.util.Collection;

public class Symtable {

    private static Symtable tabelaSimbolo;
    private Collection<EntryClass> mainTable;
    private Collection<EntryVar> globais;
    /*public static synchronized Symtable getInstance() {
     if (tabelaSimbolo == null) {
     tabelaSimbolo = new Symtable ();
     }
     return tabelaSimbolo;
     }*/
    public static String INTEGER = "integer";
    public static String CHAR = "char";
    public static String STRING = "string";
    public static String FLOAT = "float";
    public static String BOOLEAN = "boolean";
    private boolean main;

    public Symtable() {
        mainTable = new ArrayList<>();
        globais = new ArrayList<>();
        //errosSemanticos = new ArrayList<>();
        mainTable.add(new EntryClass("integer", null));
        mainTable.add(new EntryClass("float", null));
        mainTable.add(new EntryClass("string", null));
        mainTable.add(new EntryClass("boolean", null));
        mainTable.add(new EntryClass("char", null));
        main = false;

    }

    public Collection<EntryClass> getMainTable() {

        return mainTable;
    }

    public void setMainTable(Collection<EntryClass> mainTable) {
        this.mainTable = mainTable;
    }

    public Collection<EntryVar> getGlobais() {
        return globais;
    }

    public void setGlobais(Collection<EntryVar> globais) {
        this.globais = globais;
    }

    public void addClass(EntryClass classe) {
        mainTable.add(classe);
    }

    public boolean hasMain() {
        return main;
    }

    public void setMain(boolean main) {
        this.main = main;
    }

    public EntryClass getClass(String nome) {
        for (EntryClass classe : mainTable) {
            if (classe.getName().equals(nome)) {
                return classe;
            }
        }
        return null;
    }

    public EntryVar getVarGlobal(String nome) {
        for (EntryVar var : globais) {
            if (var.getName() != null) {
                if (var.getName().equals(nome)) {
                    return var;
                }
            }
        }
        return null;
    }

    public EntryVar contain(String nome, EntryClass classe, EntryMethod metodo) {

        if (metodo != null) {
            for (EntryVar var : metodo.getParams()) {
                if (var.getName() != null) {
                    if (var.getName().equals(nome)) {
                        return var;
                    }
                }
            }
            for (EntryVar var : metodo.getVariaveis()) {
                if (var.getName() != null) {
                    if (var.getName().equals(nome)) {
                        return var;
                    }
                }
            }
        }
        if (classe != null) {
            for (EntryVar var : classe.getVariaveis()) {
                if (var.getName() != null) {
                    if (var.getName().equals(nome)) {
                        return var;
                    }
                }
            }
            if (classe.hasSuperClass()) {
                EntryClass classePai = classe.getParent();
                for (EntryVar var : classePai.getVariaveis()) {
                    if (var.getName() != null) {
                        if (var.getName().equals(nome)) {
                            return var;
                        }
                    }
                }
            }
        }
        for (EntryVar var : globais) {
            if (var.getName() != null) {
                if (var.getName().equals(nome)) {
                    return var;
                }
            }
        }

        return null;
    }
}
